﻿
using Entities.PlatAdmin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Wq.Core.Common;
using Wq.Core.Common.Helper;
using Wq.Core.Extensions;
using Wq.Core.Extensions.Assembly.AutoMapper;
using Wq.Core.Extensions.Assembly.Jwt;
using Wq.Core.Extensions.Assembly.Redis;
using Wq.Core.Model;
using Wq.Core.PlatAdminService;
using Wq.Core.PlatAdminService.Models;

namespace Wq.Core.Application.Manager
{
   public class ManagerApplication: BaseApplication
    {
      
        private readonly RoleService roleService;
        private readonly ManagerService managerService;
        private readonly BaseRepository redisRepository;
        public ManagerApplication( 
                RoleService roleService, 
                ManagerService managerService, 
                BaseRepository redisRepository)
        {
            this.roleService = roleService;
            this.managerService = managerService;
            this.redisRepository = redisRepository;
        
        }

        #region 权限组

        /// <summary>
        /// 添加权限组
        /// </summary>
        /// <param name="role"></param>
        /// <returns></returns>
        public MessageModel SaveRole(RoleEditor role)
        {
            Verify(role);
            if (role.Id > 0)
                roleService.Save(role);
            else
                roleService.Create(role);
            return SuccessResult();
        }
        public void Verify(RoleEditor editor)
        {
            if (string.IsNullOrEmpty(editor.Name))
                throw new MyException("权限组名称不能空");
        }

        /// <summary>
        /// 获取权限组
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public MessageModel Details(long id)
        {
            var privileges = roleService.GetPrivilege();
            var role = roleService.Details(id);
            return SuccessResult(new { Privileges = privileges, Role = role });
          
        }

      

        /// <summary>
        /// 获取权限组列表
        /// </summary>
        /// <returns></returns>
        public MessageModel GetRoles()
        {
            return SuccessResult(roleService.GetList());
        }

        /// <summary>
        /// 删除权限组
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public MessageModel DeleteRole(long id)
        {
            var model = roleService.GetById(id);
            if (model.Number > 0)
                throw new MyException("权限组下面存在管理员不能进行删除");
            roleService.Delete(id);
            return SuccessResult();

        }

        /// <summary>
        /// 获取某个会员下的权限路径
        /// </summary>
        /// <param name="managerId"></param>
        /// <returns></returns>
        public MessageModel GetUsableMenus(long managerId)
        {
            var privileges = roleService.GetPrivilege();
            var manager =  managerService.GetById(managerId);

            if (manager.RoleId > 0)
            {
               var rolePrivilege = roleService.GetRolePrivilege(manager.RoleId);
                List<Menu> menus = new List<Menu>();
                privileges.ForEach(item => {
                    var oneMenu = GetMenu(item , rolePrivilege);
                    if (item.Children != null)
                    {
                        item.Children.ForEach(two => {
                            var towMenu = GetMenu(two, rolePrivilege);

                            #region 三级目录
                            if (two.Children != null)
                            {
                                two.Children.ForEach(three => {
                                    var threeMenu = GetMenu(three, rolePrivilege);
                                    if (threeMenu != null)
                                    {
                                        if (towMenu == null)
                                            towMenu = Assignment(two, rolePrivilege);
                                        if (towMenu.Children == null) towMenu.Children = new List<Menu>();
                                        towMenu.Children.Add(threeMenu);
                                    }
                                });
                            }
                            
                            #endregion

                            if (towMenu != null)
                            {
                                if (oneMenu == null)
                                    oneMenu = Assignment(item, rolePrivilege);
                                if (oneMenu.Children == null) oneMenu.Children = new List<Menu>();
                                oneMenu.Children.Add(towMenu);
                            }

                        });
                    }
                    
                    if (oneMenu != null)
                        menus.Add(oneMenu);
                   
                });

                return SuccessResult(menus);
            }

            return SuccessResult(privileges);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="children"></param>
        /// <param name="roleId"></param>
        /// <returns></returns>
        public Menu GetMenu(Menu children, List<RolePrivilegeInfo> rolePrivilege)
        {
            Menu menu = null;
            var roles = rolePrivilege.Select(p => p.Route).Distinct().ToList();
           
            if (roles.Contains(children.Route))
            {
                menu = Assignment(children, rolePrivilege);
            }
            return menu;
        }

        /// <summary>
        /// 赋值
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public Menu Assignment(Menu source, List<RolePrivilegeInfo> rolePrivilege)
        {
            var privileges = rolePrivilege.Select(p => p.Privilege).Distinct().ToList();
            return  new Menu()
            {
                Route = source.Route,
                Name = source.Name,
                Path = source.Path,
                Icon = source.Icon,
                Permissions = source.Permissions != null ? source.Permissions.Where(p => privileges.Contains(p.Id)).ToList() : null,
                Children = null
            };
        }
        #endregion

        #region 管理员

        public MessageModel List(PageModel<ManagerQuery> pageModel)
        {
            int count = 0;
            return SuccessResult(managerService.List(pageModel, ref count), count);
        }

        public MessageModel SaveManager(ManagerEditor manager)
        {
            ManagerVerify(manager);
            if (manager.Id > 0)
                managerService.Save(manager);
            else
                managerService.Create(manager);
            return SuccessResult();
        }
        /// <summary>
        /// 添加编辑管理员
        /// </summary>
        /// <param name="login"></param>
        /// <returns></returns>
        public void ManagerVerify(ManagerEditor manager) 
        {
            //检查输入合法性
            if (string.IsNullOrWhiteSpace(manager.Username))
                throw new MyException("请填写用户名");
            manager.Username = manager.Username.Trim(); //清除空格
            if (string.IsNullOrWhiteSpace(manager.Password))
                throw new MyException("请填写密码");
            manager.Password = manager.Password.Trim(); //清除空格

            if(manager.Id  == 0 && managerService.Count(p => p.UserName == manager.Username) > 0)
                throw new MyException("用户名已存在");
            if (manager.Id > 0 && managerService.Count(p => p.UserName == manager.Username && p.Id != manager.Id) > 0)
                throw new MyException("用户名已存在");

        }

        /// <summary>
        /// 删除管理员
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public MessageModel RemoveManager(long id)
        {
            managerService.Delete(id);
            return SuccessResult();
        }

        /// <summary>
        /// 获取Token
        /// </summary>
        /// <param name="login"></param>
        /// <returns></returns>
        public MessageModel GetToken(string name,string password)
        {
          
            var manager = managerService.GetFirst(p => p.UserName == name);
            if(manager == null)
                throw new MyException("用户不存在");
            password = EncryptionHelper.GetPasswrodWithTwiceEncode(password, manager.PasswordSalt);
            if (manager.Password != password)
                throw new MyException("密码错误");
            string access_token = JWTHelper.IssueJwt(new JwtUserModel
            {
                UserId = manager.Id.ObjToString(),
                UserRole = "Manager",
                UserName = manager.UserName,
                UserBirthDay = DateTime.Now
            });
            var refresh_token = Guid.NewGuid().ToString("N");
            var refreshToken = new RefreshToken()
            {
                Token = refresh_token,
                UserId = manager.Id
               
            };
         
            Task task = redisRepository.Set(CacheKey.RefreshToken(refresh_token), refreshToken, TimeSpan.FromMinutes(60));
            var expire = double.Parse(Appsettings.app("JwtSettings:Expire"));

            return SuccessResult(new { AccessToken = access_token, RefreshToken = refresh_token });
        }

        /// <summary>
        /// 刷新Token
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public MessageModel RefreshToken(string token)
        {
         
            var refreshToken = redisRepository.Get<RefreshToken>(CacheKey.RefreshToken(token)).Result;
            if (refreshToken == null) 
                return FailResult("token已过期");
            else
            {
                var manager = managerService.GetFirst(p => p.Id == refreshToken.UserId);
                string access_token = JWTHelper.IssueJwt(new JwtUserModel
                {
                    UserId = manager.Id.ObjToString(),
                    UserRole = "Manager",
                    UserName = manager.UserName,
                    UserBirthDay = DateTime.Now
                });
                var refresh_token = Guid.NewGuid().ToString("N");
                var newtoken = new RefreshToken()
                {
                    Token = refresh_token,
                    UserId = manager.Id

                };
                Task task = redisRepository.Set(CacheKey.RefreshToken(refresh_token), newtoken, TimeSpan.FromMinutes(60));
                var expire = double.Parse(Appsettings.app("JwtSettings:Expire"));
                return SuccessResult(new { AccessToken = access_token, RefreshToken = refresh_token });
            }
        }

        #endregion





    }
}
